﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Text;

using System.Diagnostics;

namespace BusLib
{
    public partial class Bus
    {
        internal void Update(AvlService.AvlReport report)
        {
            Debug.Assert(VehicleNum == report.vehicleID);

            BusLibDataContext db = BusLibDataContext.db;

            if (db.Connection.State == System.Data.ConnectionState.Closed)  
                db.Connection.Open();
            using (db.Transaction = db.Connection.BeginTransaction())
            {

                db.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, this);
                Route = Route.GetRouteByNumber(report.routeID);
                db.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, Route);

                System.DateTime time = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Add(new TimeSpan(report.absoluteTime * TimeSpan.TicksPerMillisecond));

                // Maybe add an event:
                Event e = Event.Get("Position", this, time, Route);
                if (e == null)
                {
                    // e = GetLatestEvent();
                    // if we have an event that exactly matches, except for the time,
                    // just update the time.
                    if (e == null)
                    {
                        e = new Event();
                        e.EventType = "Position";
                        e.Time = time;
                        e.Bus = this;
                        e.Route = Route;
                        e.Latitude = report.latitude;
                        e.Longitude = report.longitude;
                        e.Heading = report.heading;
                        e.Direction = "???";
                        this.Events.Add(e);
                        Route.Events.Add(e);
                    }

                    CurrentLatitude = report.latitude;
                    CurrentLongitude = report.longitude;
                    CurrentHeading = report.heading;
                    LastUpdateTime = time;
                }
                db.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict);
                db.Transaction.Commit();
                db.Transaction = null;
            }
        }

        public Event GetLatestEvent()
        {
            BusLibDataContext db = BusLibDataContext.db;

            return Events.First(e => e.VehicleNum == VehicleNum );
        }

        public Event[] GetLatestEventsByTime(TimeSpan t)
        {
            BusLibDataContext db = BusLibDataContext.db;

            return Events.Where(e => e.Time >= DateTime.Now - t)
                            .OrderBy(e => e.Time).ToArray();
        }

        static public Bus GetBusByNumber(int vehicleId)
        {
            BusLibDataContext db = BusLibDataContext.db;

            // Try to find it in the DB:
            if (db.Bus.Any(b => b.VehicleNum == vehicleId))
            {
                return db.Bus.Single(b => b.VehicleNum == vehicleId);
            }
            else
            {
                Bus b = new Bus();
                b.VehicleNum = vehicleId;
                //b.LastUpdateTime = System.DateTime.Now;
                db.Bus.InsertOnSubmit(b);
                db.SubmitChanges();
                return b;
            }
        }
    }
}
